﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using System.Xml;
using Core.BOL;
using Core.DAL;
using Core.Extentions;

namespace ScoutNET.Controllers
{
    public class SitemapController : ApplicationController
    {
        private SectionRepository ser = new SectionRepository();
        private StaffRepository sr = new StaffRepository();
        private NewsRepository nr = new NewsRepository();
        private AlbumsRepository ar = new AlbumsRepository();
        private ConvocRepository cr = new ConvocRepository();

        #region View
        //
        // GET: /Sitemap.xml
        [OutputCache(CacheProfile = "Sitemap")]
        public FileStreamResult Sitemap()
        {
            string url = ConfigurationManager.AppSettings["SiteUrl"];
            List<Post> lPosts = new List<Post>();

            #region Single pages
            lPosts.Add(new Post()
            {
                ChangeFreq = Frequency.Weekly,
                Loc = string.Format("{0}/Profil/RetrieveProfil", url),
                Priority = 1
            });
            lPosts.Add(new Post()
            {
                ChangeFreq = Frequency.Weekly,
                Loc = string.Format("{0}/Profil/Inscription", url),
                Priority = 1
            });
            lPosts.Add(new Post()
            {
                ChangeFreq = Frequency.Weekly,
                Loc = string.Format("{0}/Membres/Index", url),
                Priority = 1
            });
            lPosts.Add(new Post()
            {
                ChangeFreq = Frequency.Weekly,
                Loc = string.Format("{0}/Liens/Index", url),
                Priority = 1
            });
            lPosts.Add(new Post()
            {
                ChangeFreq = Frequency.Weekly,
                Loc = string.Format("{0}/RSS/Index", url),
                Priority = 1
            });
            #endregion

            #region Contact
            List<tSite_Section> lSections = ser.GetSections();
            foreach (tSite_Section sections in lSections)
            {
                lPosts.Add(new Post()
                {
                    ChangeFreq = Frequency.Weekly,
                    Loc = string.Format("{0}/{1}/{2}/{3}"
                    , url
                    , sections.SystemName.UppercaseFirst()
                    , "Contact"
                    , "Index"),
                    Priority = 1
                });
            }
            #endregion

            //Add Satf, Convoc, News, Camps Link
            lSections = lSections.Where(p => p.AdministrativeSection == false).ToList();
            foreach (tSite_Section sections in lSections)
            {
                #region Home section
                lPosts.Add(new Post()
                {
                    ChangeFreq = Frequency.Weekly,
                    Loc = string.Format("{0}/{1}",url , sections.SystemName.UppercaseFirst()),
                    Priority = 1
                });
                #endregion

                #region Convoc
                lPosts.Add(new Post()
                {
                    ChangeFreq = Frequency.Weekly,
                    Loc = string.Format("{0}/{1}/{2}/{3}"
                    , url
                    , sections.SystemName.UppercaseFirst()
                    , "Convoc"
                    , "Index"),
                    Priority = 1
                });
                #endregion

                #region Staff
                lPosts.Add(new Post()
                {
                    ChangeFreq = Frequency.Weekly,
                    Loc = string.Format("{0}/{1}/{2}/{3}"
                    , url
                    , sections.SystemName.UppercaseFirst()
                    , "Staff"
                    , "Index"),
                    Priority = 1
                });

                //Archives
                int startYear = sr.GetFirstYearBySystemName(sections.SystemName);
                int endYear = sr.GetLastYearBySystemName(sections.SystemName);
                if (endYear != -1 && startYear != -1)
                {
                    endYear = (endYear == DateTime.Now.GetNowTimeByTimeZone().Year) ? endYear - 1 : endYear;
                    for (int i = endYear; i >= startYear; i--)
                    {
                        lPosts.Add(new Post()
                        {
                            ChangeFreq = Frequency.Monthly,
                            Loc = string.Format("{0}/{1}/{2}/{3}/{4}"
                            , url
                            , sections.SystemName.UppercaseFirst()
                            , "Staff"
                            , "Archives"
                            , i.ToString()),
                            Priority = 1
                        });
                    }
                }
                #endregion

                #region Agenda
                lPosts.Add(new Post()
                {
                    ChangeFreq = Frequency.Weekly,
                    Loc = string.Format("{0}/{1}/{2}/{3}"
                    , url
                    , sections.SystemName.UppercaseFirst()
                    , "Agenda"
                    , "Index"),
                    Priority = 1
                });
                #endregion

                #region Camp
                lPosts.Add(new Post()
                {
                    ChangeFreq = Frequency.Weekly,
                    Loc = string.Format("{0}/{1}/{2}/{3}"
                    , url
                    , sections.SystemName.UppercaseFirst()
                    , "Camps"
                    , "Index"),
                    Priority = 1
                });

                lPosts.Add(new Post()
                {
                    ChangeFreq = Frequency.Weekly,
                    Loc = string.Format("{0}/{1}/{2}/{3}"
                    , url
                    , sections.SystemName.UppercaseFirst()
                    , "Camps"
                    , "List"),
                    Priority = 1
                });
                #endregion
            }

            #region Gallery
            List<tSite_Photos_Album> lAlbums = ar.GetAlbums();
            foreach (tSite_Photos_Album album in lAlbums)
            {
                lPosts.Add(new Post()
                {
                    ChangeFreq = Frequency.Weekly,
                    Loc = string.Format("{0}/{1}/{2}/{3}/{4}/{5}"
                    , url
                    , album.SystemName.UppercaseFirst()
                    , "Album"
                    , "Index"
                    , album.ID
                    , album.Title.ParseUrl()),
                    Priority = 1
                });
            }
            #endregion

            #region News
            List<tSite_New> lnews = nr.GetNews(0, -1);
            foreach (tSite_New news in lnews)
            {
                lPosts.Add(new Post()
                {
                    ChangeFreq = Frequency.Weekly,
                    Loc = string.Format("{0}/{1}/{2}/{3}/{4}/{5}"
                    , url
                    , news.SystemName.UppercaseFirst()
                    , "News"
                    , "Details"
                    , news.ID
                    , news.Title.ParseUrl()),
                    Priority = 1
                });
            }
            #endregion

            #region Convoc
            List<tSite_Convoc> lconvoc = cr.GetAllConvoc();
            foreach (tSite_Convoc convoc in lconvoc)
            {
                lPosts.Add(new Post()
                {
                    ChangeFreq = Frequency.Weekly,
                    Loc = string.Format("{0}/{1}/{2}/{3}/{4}"
                    , url
                    , convoc.SystemName.UppercaseFirst()
                    , "Convoc"
                    , "Detail"
                    , convoc.ID),
                    Priority = 1
                });
            }
            #endregion

            #region Membres
            MembershipUserCollection muc = Membership.GetAllUsers();
            foreach (MembershipUser mu in muc)
            {
                lPosts.Add(new Post()
                {
                    ChangeFreq = Frequency.Weekly,
                    Loc = string.Format("{0}/{1}/{2}/{3}/{4}"
                    , url
                    , "Membres"
                    , "Details"
                    , mu.ProviderUserKey.ToString()
                    , mu.UserName.ParseUrl()),
                    Priority = 1
                });
            }
            #endregion

            return new FileStreamResult(GetSiteMapXML(lPosts), "text/xml");
        }

        //
        // GET: /Sitemap/Index
        public ActionResult Index()
        {
            // Meta Tag
            ViewData["PageTitle"] = Resources.Sitemap_Index_Title;
            ViewData["PageDescription"] = Resources.Sitemap_Index_Description;

            //Breadcrumb
            string[] saBreadcrumb = new String[2];
            saBreadcrumb[0] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
            saBreadcrumb[1] = Resources.Sitemap_Index_Breadcrumb;
            ViewData["Breadcrumb"] = saBreadcrumb;

            string key = "Sitemap";

            if (this.HttpContext.Cache[key] == null)
            {
                List<Sitemap> lSitemap = new List<Sitemap>();
                List<tSite_Section> lSections = ser.GetSections();
                lSections = lSections.Where(p => p.AnimationSection == true).ToList();
                Sitemap siteMap = new Sitemap();

                // Album
                foreach (tSite_Section s in lSections)
                {
                    siteMap = new Sitemap();
                    siteMap.Topic = "Albums";
                    siteMap.Title = "Albums " + s.SystemName;
                    siteMap.Url = string.Format("/{0}/Galerie/Index", s.SystemName.UppercaseFirst());

                    List<vw_Site_Photos_Album> lSiteAlbum = ar.GetAlbumBySectionName(s.SystemName, 0, 15);
                    List<Sitemap> smAlbums = new List<Sitemap>();
                    foreach (vw_Site_Photos_Album item in lSiteAlbum)
                    {
                        Sitemap smAlbum = new Sitemap();
                        smAlbum.Title = item.Title;
                        smAlbum.Url = string.Format("/{0}/Album/Index/{1}/{2}", s.SystemName.UppercaseFirst(), item.ID, item.Title.ParseUrl());
                        smAlbums.Add(smAlbum);
                    }
                    siteMap.Child = smAlbums;
                    lSitemap.Add(siteMap);
                }

                // News
                foreach (tSite_Section s in lSections)
                {
                    siteMap = new Sitemap();
                    siteMap.Topic = "News";
                    siteMap.Title = "News " + s.SystemName;
                    siteMap.Url = string.Format("/{0}/News/Index", s.SystemName.UppercaseFirst());

                    List<tSite_New> lSitenews = nr.GetNewsBySectionName(s.SystemName, 0, 10);
                    List<Sitemap> smNews = new List<Sitemap>();
                    foreach (tSite_New item in lSitenews)
                    {
                        Sitemap smNew = new Sitemap();
                        smNew.Title = item.Title;
                        smNew.Url = string.Format("/{0}/News/Details/{1}/{2}", s.SystemName.UppercaseFirst(), item.ID, item.Title.ParseUrl());
                        smNews.Add(smNew);
                    }
                    siteMap.Child = smNews;

                    lSitemap.Add(siteMap);
                }

                // Convoc
                foreach (tSite_Section s in lSections)
                {
                    siteMap = new Sitemap();
                    siteMap.Topic = "Convoc";
                    siteMap.Title = "Convoc " + s.SystemName;
                    siteMap.Url = string.Format("/{0}/Convoc/Index", s.SystemName.UppercaseFirst());
                    lSitemap.Add(siteMap);
                }

                // Staff
                foreach (tSite_Section s in lSections)
                {
                    siteMap = new Sitemap();
                    siteMap.Topic = "Staff";
                    siteMap.Title = "Staff " + s.SystemName;
                    siteMap.Url = string.Format("/{0}/Staff/Index", s.SystemName.UppercaseFirst());

                    //Archives
                    int startYear = sr.GetFirstYearBySystemName(s.SystemName);
                    int endYear = sr.GetLastYearBySystemName(s.SystemName);
                    if (endYear != -1 && startYear != -1)
                    {
                        endYear = (endYear == DateTime.Now.GetNowTimeByTimeZone().Year) ? endYear - 1 : endYear;
                        List<Sitemap> lStaffAchives = new List<Sitemap>();
                        for (int i = endYear; i >= startYear; i--)
                        {
                            Sitemap staffAchives = new Sitemap();
                            staffAchives.Title = "Staff " + s.SystemName + " " + i + " - " + (i + 1);
                            staffAchives.Url = string.Format("{0}/{1}/{2}/{3}"
                                , s.SystemName.UppercaseFirst()
                                , "Staff"
                                , "Archives"
                                , i.ToString());
                            lStaffAchives.Add(staffAchives);
                        }
                        siteMap.Child = lStaffAchives;
                    }
                    lSitemap.Add(siteMap);
                }

                // Camp
                foreach (tSite_Section s in lSections)
                {
                    siteMap = new Sitemap();
                    siteMap.Topic = "Camps";
                    siteMap.Title = "Camps " + s.SystemName;
                    siteMap.Url = string.Format("/{0}/Camps/Index", s.SystemName.UppercaseFirst());
                    lSitemap.Add(siteMap);
                }

                // Contact
                foreach (tSite_Section s in lSections)
                {
                    siteMap = new Sitemap();
                    siteMap.Topic = "Contact";
                    siteMap.Title = "Contact " + s.SystemName;
                    siteMap.Url = string.Format("/{0}/Contact/Index", s.SystemName.UppercaseFirst());
                    lSitemap.Add(siteMap);
                }

                this.HttpContext.Cache.Insert(key, lSitemap, null, DateTime.Now.AddDays(2), System.Web.Caching.Cache.NoSlidingExpiration);
            }

            return View(this.HttpContext.Cache[key]);
        }
        #endregion

        private MemoryStream GetSiteMapXML(List<Post> lPosts)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.IndentChars = ("\t");
            settings.Encoding = Encoding.UTF8;

            MemoryStream ms = new MemoryStream();

            using (XmlWriter writer = XmlWriter.Create(ms, settings))
            {
                writer.WriteStartElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");

                foreach (Post post in lPosts)
                {
                    writer.WriteStartElement("url");
                    writer.WriteElementString("loc", post.Loc);

                    writer.WriteElementString("changefreq", post.ChangeFreq.ToString());
                    writer.WriteElementString("priority", post.Priority.ToString());
                    writer.WriteEndElement();
                }

                writer.WriteEndElement();
            }
            ms.Position = 0;

            return ms;
        }

    }
}
